import json
import subprocess
import sys
import PySimpleGUI as sg

name_dict = {}
try:
    with open('cn_name.json', 'r', encoding='utf-8') as file:
        name_dict = json.load(file)
except IOError:
    print('无法加载cn_name.json')

# 修复高DPI感知
if sys.platform == 'win32':
    try:
        import ctypes

        ctypes.OleDLL('shcore').SetProcessDpiAwareness(1)
    except (ImportError, AttributeError, OSError):
        pass


class App:
    def __init__(self, name, pkgname, version):
        self.name = name
        self.pkgname = pkgname
        self.version = version


def uninstall(app):
    cmd1 = f"DISM /Online /Remove-ProvisionedAppxPackage /PackageName:{app.pkgname}"
    cmd2 = f"Get-AppxPackage -Name '*{app.name}*' | Remove-AppxPackage"
    result = subprocess.run(cmd1, capture_output=True, text=True)
    result2 = subprocess.run(["powershell", "-Command", cmd2], capture_output=True, text=True)
    if result.returncode == 0:
        print(f'{app.name} 预装卸载成功')
        window[app.name].update(text_color='red')
    else:
        print(f'{app.name} 卸载失败!!! 参考信息:\n {result.stdout}')
    if result2.returncode == 0:
        print(f'{app.name} 用户卸载成功')
        window[app.name].update(text_color='red')
    else:
        print(f'{app.name} 用户卸载失败!!! 参考信息:\n {result2.stdout}')


cmd = "DISM /Online /Get-ProvisionedAppxPackages"
echo_list = []
try:
    echo = subprocess.run(cmd, capture_output=True, text=True).stdout
except Exception as e:
    print(f'无法获取预装应用列表, 错误信息:\n {e}')
echo_list = echo.split('\n\n')
apps = {}
for x in echo_list:
    if "PackageName" in x:
        name = x.split('\n')[0].split(':')[1].strip()
        version = x.split('\n')[1].split(':')[1].strip()
        packgename = x.split('\n')[4].split(':')[1].strip()
        apps[name] = App(name, packgename, version)

sg.set_options(font=('微软雅黑', 8))
sg.theme('SystemDefaultForReal')
row_cap = 4 if len(apps.values()) > 33 else 3
frame_layout = []
row_layout = []
for index, app in enumerate(apps.values()):
    if index % row_cap == 0:
        row_layout = []
    cn_name = name_dict.get(app.name, app.name)
    column_layout = [[
        sg.Checkbox(cn_name, size=(34, 1), key=app.name),
        sg.Button('卸载', key=f'uninstallbt-{app.name}', button_color=('white', 'red'))
    ]]
    row_layout.append(sg.Column(column_layout))
    if len(row_layout) == row_cap or index == len(apps.values()) - 1:
        frame_layout.append(row_layout)
layout = [
    [sg.Frame('APPX预装包管理', frame_layout)],
    [
        sg.Button('全选'),
        sg.Button('反选'),
        sg.Button('全不选'),
        sg.Button('一键卸载', button_color=('white', 'red')),
        sg.Button('输出信息'),
        sg.Button('输出名称')
    ]
]

window = sg.Window('APPX预装包管理 240724', layout)

while True:
    event, values = window.read()
    if event in (sg.WINDOW_CLOSED, 'Cancel'):
        break
    if event.startswith('uninstallbt-'):
        app_name = event.split('bt-')[1]
        response = sg.popup_yes_no(f'确定要卸载 {app_name} 吗？\n===将从当前用户和系统彻底卸载===', title='确认')
        if response == 'Yes':
            uninstall(apps[app_name])

    if event == '全选':
        for app in apps.values():
            window[app.name].update(True)
    if event == '反选':
        for app in apps.values():
            window[app.name].update(not window[app.name].get())
    if event == '全不选':
        for app in apps.values():
            window[app.name].update(False)
    if event == '一键卸载':
        selected_apps = [app for app in apps.values() if window[app.name].get()]
        if sg.popup_yes_no(f'确定要卸载选中的{len(selected_apps)}个应用吗?') == 'Yes':
            for app in selected_apps:
                uninstall(app)
    if event == '输出信息':
        selected_apps = [app for app in apps.values() if window[app.name].get()]
        count = 0
        for app in selected_apps:
            count += 1
            print(f'{count} {"=" * 50}\n名称:{app.name}\n包名:{app.pkgname}\n版本:{app.version}')
    if event == '输出名称':
        selected_apps = [app for app in apps.values() if window[app.name].get()]
        print('\n'.join([app.name for app in selected_apps]))

window.close()
